package com.oldman.controller;

import com.oldman.domain.Elderlyinfo;
import com.oldman.domain.ResultVO;
import com.oldman.service.ElderlyinfoService;
import com.oldman.service.FaceService;
import com.oldman.utils.*;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
public class AuthController {
    @Autowired
    private FaceService faceService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ElderlyinfoService elderlyinfoService;



    @PostMapping("auth/regist")
    public ResultVO regist(@RequestBody Elderlyinfo e){
        AjaxResult result = elderlyinfoService.regist(e);
        int code = (int) result.get(AjaxResult.CODE_TAG);
        return code==200?ResultVO.success():ResultVO.fail();
    }

    @PostMapping("auth/getCode")
    public ResultVO getCode(@RequestBody String phone){
        if (!StringUtils.hasText(phone)){
            throw new RuntimeException("手机号为空");
        }
        String code = RandomCode.randomCode();
        CodeUtil.sendCode(phone,code);
        redisTemplate.opsForValue().set("loginCode",code,60, TimeUnit.SECONDS);
        return ResultVO.success();
    }


    @PostMapping("auth/login")
    public ResultVO login(@RequestBody String phone,String code){
        if (!StringUtils.hasText(phone)||!StringUtils.hasText(code)){
             throw new RuntimeException("手机号或验证码为空");
        }
        Object o = redisTemplate.opsForValue().get("loginCode");
        if (o == null) {
            throw new RuntimeException("验证码已过期，请重试");
        }
        return ResultVO.success();
    }

    @PostMapping("auth/authUser")
    public ResultVO authUser(@RequestBody String idcard,String phone){
        AjaxResult ajaxResult = elderlyinfoService.authUser(idcard, phone);
        int code = (int) ajaxResult.get(AjaxResult.CODE_TAG);
        return code==200?ResultVO.success():ResultVO.fail();
    }


    @PostMapping("auth/authFace/{file,id}")
    public ResultVO authFace(@PathVariable MultipartFile file,@PathVariable Integer id) {
        String token = redisTemplate.opsForValue().get("faceToken").toString();
        if (token == null) {
            token = faceService.getAuth();
        }

        String localBase = getDataBaseImageBase64(id);
        Map<String, String> dataBaseMap = fillMap(localBase);

        String authBase = file2Base64(file);
        Map<String, String> authMap = fillMap(authBase);

        String result = faceMatch(authMap,dataBaseMap,token);
        Map resultMap = GsonUtils.fromJson(result, Map.class);
        Integer score = (Integer) resultMap.get("score");

        return score>=80?ResultVO.success():ResultVO.fail();
    }

    private  String getDataBaseImageBase64(Integer id){
        AjaxResult info = elderlyinfoService.getInfo(Long.valueOf(id));
        Elderlyinfo e = (Elderlyinfo) info.get(AjaxResult.DATA_TAG);
        File file = new File(e.getPersonalPhoto());
        String base64 = file2Base64(file);
        return base64;
    }

    private  Map<String, String> fillMap(String base) {
        Map<String, String> map = new HashMap();
        map.put("image", base);
        map.put("image_type", "BASE64");
        return map;
    }

    private  String file2Base64(File file) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            byte[] bytes = new byte[(int) file.length()];
            fis.read(bytes);
            return Base64Util.encode(bytes);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fis.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private  String file2Base64(MultipartFile file) {
        FileInputStream fis = null;
        try {
            return Base64Util.encode(file.getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    public  String faceMatch(Map authMap,Map dataBaseMap, String token) {
        // 请求url
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/match";
        try {
            Map[] param = new Map[2];
            param[0] = authMap;
            param[1] = dataBaseMap;
            String json = GsonUtils.toJson(param);
            String result = HttpUtil.post(url, token, "application/json", json);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
